package org.xiaov.lunasql.spring.proxy;

import lombok.extern.slf4j.Slf4j;
import org.dromara.hutool.core.text.CharUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.xiaov.lunasql.engine.config.LunaSqlConfig;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * The type Prepared statement proxy.
 *
 * @author xiaovcloud
 * @since 2024/1/23 10:50
 */
@Slf4j
public class LunaPreparedStatementProxy extends AbstractPreparedStatementProxy implements PreparedStatement {

    private final LunaSqlConfig lunaConfig;

    /**
     * Instantiates a new Prepared statement proxy.
     *
     * @param connectionProxy the connection proxy
     * @param targetStatement the target statement
     * @param targetSql       the target sql
     * @param lunaConfig      lunaConfig
     */
    public LunaPreparedStatementProxy(AbstractConnectionProxy connectionProxy,
                                      PreparedStatement targetStatement,
                                      String targetSql,
                                      LunaSqlConfig lunaConfig) {
        super(connectionProxy, targetStatement, targetSql);
        this.lunaConfig = lunaConfig;
    }

    @Override
    public boolean execute() throws SQLException {
        printSql();
        return targetStatement.execute();
    }

    @Override
    public ResultSet executeQuery() throws SQLException {
        printSql();
        return targetStatement.executeQuery();
    }

    @Override
    public int executeUpdate() throws SQLException {
        printSql();
        return targetStatement.executeUpdate();
    }

    private void printSql() {
        if (!lunaConfig.isPrintSQL()) {
            return;
        }
        int index = 1;
        char[] charArray = targetSql.toCharArray();
        for (char c : charArray) {
            if (CharUtil.equals('?', c, false)) {
                Object obj = parameters.get(index++).get(0);
                if (obj instanceof String) {
                    targetSql = StrUtil.replaceFirst(targetSql, "?", "'" + StrUtil.toString(obj) + "'", false);
                } else {
                    targetSql = StrUtil.replaceFirst(targetSql, "?", StrUtil.toString(obj), false);
                }
            }
        }
        targetSql = targetSql.replaceAll("\n", " ").replaceAll("\\s+", " ");
        log.info("==>\n执行SQL：{}", targetSql);
    }
}
